package de.uni_saarland.coli.doclists.index.filesystem;

/**
 * 
 * @author stefan
 * 
 *         DiscList with cache.
 * 
 * @param <T>
 *            Type of cached objects (needs to implement IToBytes)
 */
public abstract class CachedObjectDiscList<T extends IToBytes> extends DiscList {
	/**
	 * Object cache
	 */
	private ObjectCache<T> cache;

	/**
	 * Creates an object from the byte array
	 * 
	 * @param bytes
	 *            the byte array
	 * @return the object
	 */
	public abstract T createObject(byte[] bytes);

	/**
	 * Constructor.
	 * 
	 * @param size
	 *            size of the cahce.
	 */
	public CachedObjectDiscList(int size) {
		this.cache = new ObjectCache<T>(size);
	}

	/**
	 * Returns an object. Side effects: - DiscIO if the object is not in the
	 * cache
	 * 
	 * @param id
	 *            objects id
	 * @return the object null if no object with the id exists
	 */
	public T getObject(int id) {
		T cacheDoc = this.cache.get(id);
		if (cacheDoc == null) {
			//System.out.println("read " + id);
			byte[] bytes = this.getBytes(id);

			if (bytes == null)
				return null;

			cacheDoc = this.createObject(bytes);
			
			this.cache.add(id, cacheDoc);
			cacheDoc.setListIDX(id);
			cacheDoc.setDistList(this);
		}
		return cacheDoc;
	}

	/**
	 * Adds an object to the cache. Side effect: - object calls setListIDX
	 * 
	 * @param object
	 *            the object
	 */
	public void addObject(T object) {
		int idx = (int) this.indexSize();
		object.setListIDX(idx);
		object.setDistList(this);
//		System.out.println("a idx: " + idx);
		this.addBytes(object.toBytes());
		
		this.cache.add(idx, object);

	}
	
	@Override
	public String toString() {
		return this.cache.toString();
	}
}
